import { Attachment, Note, NoteGroup } from '@/types/notes';

const LS_NOTES = 'notes.items';
const LS_GROUPS = 'notes.groups';

function uid() {
  return `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
}

export function loadGroups(): NoteGroup[] {
  try {
    const raw = localStorage.getItem(LS_GROUPS);
    const parsed = raw ? JSON.parse(raw) : [];
    return Array.isArray(parsed) ? parsed : [];
  } catch {
    return [];
  }
}

export function saveGroups(groups: NoteGroup[]) {
  localStorage.setItem(LS_GROUPS, JSON.stringify(groups));
}

export function ensureDefaultGroup(): NoteGroup[] {
  const groups = loadGroups();
  if (!groups.length) {
    const g: NoteGroup = {
      id: uid(),
      name: '默认',
      createdAt: new Date().toISOString(),
      order: 0,
    };
    const list = [g];
    saveGroups(list);
    return list;
  }
  return groups;
}

export function loadNotes(): Note[] {
  try {
    const raw = localStorage.getItem(LS_NOTES);
    const parsed = raw ? JSON.parse(raw) : [];
    return Array.isArray(parsed) ? parsed : [];
  } catch {
    return [];
  }
}

export function saveNotes(notes: Note[]) {
  localStorage.setItem(LS_NOTES, JSON.stringify(notes));
}

export function createNote(partial: Partial<Note>): Note {
  const now = new Date().toISOString();
  const note: Note = {
    id: uid(),
    title: partial.title || '',
    content: partial.content || '',
    groupId: partial.groupId ?? null,
    attachments: partial.attachments || [],
    reminderAt: partial.reminderAt || null,
    createdAt: now,
    updatedAt: now,
    timeSpent: 0,
    isTiming: false,
    timingStartAt: null,
  };
  const all = loadNotes();
  all.unshift(note);
  saveNotes(all);
  return note;
}

export function updateNote(id: string, patch: Partial<Note>): Note | null {
  const all = loadNotes();
  const idx = all.findIndex(n => n.id === id);
  if (idx === -1) return null;
  const now = new Date().toISOString();
  all[idx] = { ...all[idx], ...patch, updatedAt: now };
  saveNotes(all);
  return all[idx];
}

export function deleteNote(id: string) {
  const all = loadNotes().filter(n => n.id !== id);
  saveNotes(all);
}

export function createGroup(name: string): NoteGroup {
  const list = loadGroups();
  const g: NoteGroup = {
    id: uid(),
    name,
    createdAt: new Date().toISOString(),
    order: list.length,
  };
  list.push(g);
  saveGroups(list);
  return g;
}

export function renameGroup(id: string, name: string) {
  const list = loadGroups();
  const idx = list.findIndex(g => g.id === id);
  if (idx !== -1) {
    list[idx].name = name;
    saveGroups(list);
  }
}

export function deleteGroup(id: string) {
  const groups = loadGroups().filter(g => g.id !== id);
  saveGroups(groups);
  // 将该组下便签的 groupId 清空
  const notes = loadNotes().map(n => (n.groupId === id ? { ...n, groupId: null } : n));
  saveNotes(notes);
}

// 计时相关
export function startTiming(noteId: string) {
  const note = updateNote(noteId, { isTiming: true, timingStartAt: new Date().toISOString() });
  return note;
}

export function stopTiming(noteId: string) {
  const all = loadNotes();
  const idx = all.findIndex(n => n.id === noteId);
  if (idx === -1) return null;
  const n = all[idx];
  if (n.isTiming && n.timingStartAt) {
    const deltaSec = Math.max(0, Math.floor((Date.now() - new Date(n.timingStartAt).getTime()) / 1000));
    n.timeSpent += deltaSec;
  }
  n.isTiming = false;
  n.timingStartAt = null;
  n.updatedAt = new Date().toISOString();
  all[idx] = n;
  saveNotes(all);
  return n;
}

// 附件工具：小于 400KB 的图像转为 base64 存储
export async function fileToAttachment(file: File): Promise<Attachment> {
  const kind = file.type.startsWith('image/')
    ? 'image'
    : file.type.startsWith('video/')
    ? 'video'
    : file.type.startsWith('audio/')
    ? 'audio'
    : 'file';
  const base: Attachment = {
    id: uid(),
    kind,
    name: file.name,
    mime: file.type,
    size: file.size,
  };
  if (kind === 'image' && file.size < 400 * 1024) {
    const dataUrl = await new Promise<string>((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => resolve(reader.result as string);
      reader.onerror = reject;
      reader.readAsDataURL(file);
    });
    return { ...base, dataUrl };
  } else {
    const objectUrl = URL.createObjectURL(file);
    return { ...base, objectUrl };
  }
}